using System;
using System.Collections;
using System.Web.UI;
using NBusiness.Templates;
using NBusiness.Data;
using System.Collections.Generic;
using NBusiness.Query;

namespace NBusiness.Data.Web
{

    /// <summary>
    /// The object responsible for managing data binding
    /// to a specific entity.
    /// </summary>
    public class EntityDataSourceView : DataSourceView
    {
        private EntityDataSource _owner;

        /// <summary>
        /// Creates an instance of the object.
        /// </summary>
        /// <param name="owner">The EntityDataSource object
        /// that owns this view.</param>
        /// <param name="viewName">The name of the view.</param>
        public EntityDataSourceView(EntityDataSource owner, string viewName)
            : base(owner, viewName)
        {
            _owner = owner;
        }

        #region Select

        /// <summary>
        /// Implements the select behavior for
        /// the control by raising the Select event.
        /// </summary>
        /// <param name="arguments">Arguments object.</param>
        /// <returns>The data returned from the select.</returns>
        protected override System.Collections.IEnumerable
          ExecuteSelect(DataSourceSelectArguments arguments)
        {
            // get the object from the page
            string fieldName = null;
            SortOrder order = SortOrder.None;

            if (arguments.SortExpression.Length > 0)
            {
                string[] sortArgs = arguments.SortExpression.Split(' ');
                fieldName = sortArgs[0];

                string direction = (sortArgs.Length > 1 ? sortArgs[1] : null);
                if (direction != null)
                {
                    order = (SortOrder)Enum.Parse(typeof(SortOrder), direction, true);
                }
                else order = SortOrder.Asc;
            }
            
            SelectEntityEventArgs args = new SelectEntityEventArgs(
                arguments.StartRowIndex,
                arguments.MaximumRows,
                fieldName,
                order);
            _owner.OnSelectObject(args);

            //default total, no paging done in DAL
            if (args.Entities != null)
                arguments.TotalRowCount = args.Entities.Count;

            //Set the total number of rows 
            if (args.TotalRows > arguments.TotalRowCount) // Data Access Layer paging performed
            {
                arguments.TotalRowCount = args.TotalRows;
            }

            // now return the object as a result
            return args.Entities;
        }

        #endregion

        #region Insert
        /// <summary>
        /// Gets a value indicating whether the data source can
        /// insert data.
        /// </summary>
        public override bool CanInsert
        {
            get { return true; }
        }

        /// <summary>
        /// Implements the insert behavior for
        /// the control by raising the Insert event.
        /// </summary>
        /// <param name="values">The values from
        /// the UI that are to be inserted.</param>
        /// <returns>The number of rows affected.</returns>
        protected override int ExecuteInsert(
          IDictionary values)
        {
            // tell the page to insert the object
            InsertEntityEventArgs args =
              new InsertEntityEventArgs(values);
            _owner.OnInsertObject(args);
            return args.RowsAffected;
        }

        #endregion

        #region Delete
        /// <summary>
        /// Gets a value indicating whether the data source can
        /// delete data.
        /// </summary>
        public override bool CanDelete
        {
            get { return true; }
        }

        /// <summary>
        /// Implements the delete behavior for
        /// the control by raising the Delete event.
        /// </summary>
        /// <param name="keys">The key values from
        /// the UI that are to be deleted.</param>
        /// <param name="oldValues">The old values
        /// from the UI.</param>
        /// <returns>The number of rows affected.</returns>
        protected override int ExecuteDelete(IDictionary keys, IDictionary oldValues)
        {

            // tell the page to delete the object
            DeleteEntityEventArgs args = new DeleteEntityEventArgs(keys, oldValues);
            _owner.OnDeleteObject(args);
            return args.RowsAffected;
        }

        #endregion

        #region Update
        /// <summary>
        /// Gets a value indicating whether the data source can
        /// update data.
        /// </summary>
        public override bool CanUpdate
        {
            get { return true; }
        }

        /// <summary>
        /// Implements the update behavior for
        /// the control by raising the Update event.
        /// </summary>
        /// <param name="keys">The key values from the UI
        /// that identify the object to be updated.</param>
        /// <param name="values">The values from
        /// the UI that are to be inserted.</param>
        /// <param name="oldValues">The old values
        /// from the UI.</param>
        /// <returns>The number of rows affected.</returns>
        protected override int ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues)
        {
            // tell the page to update the object
            UpdateEntityEventArgs args = new UpdateEntityEventArgs(keys, values, oldValues);
            _owner.OnUpdateObject(args);
            return args.RowsAffected;
        }

        #endregion

        #region Other Operations
        /// <summary>
        /// Gets a value indicating whether the data source supports
        /// paging of the data.
        /// </summary>
        public override bool CanPage
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// Gets a value indicating whether the data source can
        /// retrieve the total number of rows of data. Always
        /// returns <see langword="true"/>.
        /// </summary>
        public override bool CanRetrieveTotalRowCount
        {
            get { return true; }
        }

        /// <summary>
        /// Gets a alue indicating whether the data source supports
        /// sorting of the data. Always returns <see langword="false"/>.
        /// </summary>
        public override bool CanSort
        {
            get
            {
                return true;
            }
        }

        #endregion
    }
}